/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package estsapp.expertos;

import estsapp.entidades.CentroTrabajo;
import estsapp.entidades.DetalleOrden;
import estsapp.entidades.EtapaFabricacion;
import estsapp.entidades.OrdenDeProduccion;
import estsapp.entidades.ProductoTerminado;
import estsapp.expertos.excepciones.ABMCentroDeTrabajoException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import persistencia.Conexion;
import persistencia.Fachada;
import persistencia.exceptions.ExcepcionFachada;

/**
 *
 * @author Juan
 */
public class ExpertoABMCentroDeTrabajo implements Experto {

    public boolean buscarProducto(CentroTrabajo centro) {
        Criteria crit = Fachada.getInstancia().crearCriterio(ProductoTerminado.class);
        crit.add(Restrictions.eq("vigente", true));
        List prod = Fachada.getInstancia().buscar(ProductoTerminado.class, crit);

        for (Object producto : prod) {
            List etapas = ((ProductoTerminado) producto).getRutaFabricacion().getEstapasFabricacion();

            for (Object etapita : etapas) {
                if (((EtapaFabricacion) etapita).getCentroDeTrabajo().equals(centro)) {
                    return true;
                }
            }
        }
        return false;

    }

    public void darDeBaja(CentroTrabajo centro) throws ABMCentroDeTrabajoException, ExcepcionFachada {



        boolean encontrado = false;
        Criteria criterioOrdenActiva = Fachada.getInstancia().crearCriterio(OrdenDeProduccion.class);
        criterioOrdenActiva.add(Restrictions.eq("ordenActiva", true));
        List ordenesActivas = Fachada.getInstancia().buscar(OrdenDeProduccion.class, criterioOrdenActiva);

        for (Object orden : ordenesActivas) {
            List detalles = new ArrayList();
            if (((OrdenDeProduccion) orden).getListaDetalles() != null) {
                detalles = ((OrdenDeProduccion) orden).getListaDetalles();

                for (Object detalle : detalles) {
                    List etapas = new ArrayList();

                    if (((DetalleOrden) detalle).getProductoTerminado().getRutaFabricacion() != null) {

                        if (((DetalleOrden) detalle).getProductoTerminado().getRutaFabricacion().getEstapasFabricacion() != null) {
                            etapas = ((DetalleOrden) detalle).getProductoTerminado().getRutaFabricacion().getEstapasFabricacion();


                            for (Object etapa : etapas) {
                                if (centro == ((EtapaFabricacion) etapa).getCentroDeTrabajo()) {
                                    encontrado = true;
                                }
                            }
                        }
                    }
                }
            }
        }
        if (!buscarProducto(centro)) {


            if (!encontrado) {
                centro.setVigente(false);
                Fachada.getInstancia().guardar(centro);
            } else {
                JOptionPane.showMessageDialog(null, "Centro de trabajo actualmente necesario para una orden pendiente", "Notificación", JOptionPane.INFORMATION_MESSAGE);
                throw new ABMCentroDeTrabajoException("No se pudo eliminar el centro de trabajo");

            }
        } else {
            JOptionPane.showMessageDialog(null, "No se puede eliminar el centro ya que hay productos que se fabrican en este centro");
        }
    }

    public void guardar(CentroTrabajo centro) throws ABMCentroDeTrabajoException {
        validarMaterial(centro);
        validarExistencia(centro);
        String codigo;
        if (centro.getId() == null) {
            codigo = ((ExpertoCodigoBrisch) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.GENERAR_CODIGO)).generarCodigo(centro);
            centro.setCodigo(codigo);
        }


        try {
            Conexion.getInstancia().iniciarTX();
            Fachada.getInstancia().guardar(centro);
            Conexion.getInstancia().confirmarTx();
        } catch (ExcepcionFachada ex) {
            Conexion.getInstancia().deshacerTx();
            Logger.getLogger(ExpertoABMCentroDeTrabajo.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public List buscarCentros() {
        Criteria cirterioCentro = Fachada.getInstancia().crearCriterio(CentroTrabajo.class);
        return Fachada.getInstancia().buscar(CentroTrabajo.class, cirterioCentro);
    }

    public List buscarCentros(String nombre, String codigo) {
        Criteria criterioCentros = Fachada.getInstancia().crearCriterio(CentroTrabajo.class);
        if (!"".equals(nombre)) {
            criterioCentros.add(Restrictions.ilike("nombre", nombre));
        }
        if (!"".equals(codigo)) {
            criterioCentros.add(Restrictions.ilike("codigo", codigo));
        }
        return Fachada.getInstancia().buscar(CentroTrabajo.class, criterioCentros);
    }

    private void validarMaterial(CentroTrabajo centro) throws ABMCentroDeTrabajoException {

        if (centro.getNombre().length() == 0) {
            throw new ABMCentroDeTrabajoException("Falta nombre");
        }

    }

    private void validarExistencia(CentroTrabajo centro) throws ABMCentroDeTrabajoException {
        if (centro.getId() != null) {
            return;
        }
        Criteria criterio = Fachada.getInstancia().crearCriterio(CentroTrabajo.class);
        criterio.add(Restrictions.eq("id", centro.getId()));

        if (!Fachada.getInstancia().buscar(CentroTrabajo.class, criterio).isEmpty()) {
            throw new ABMCentroDeTrabajoException("Centro ya existente");
        }
    }

    public boolean validarExistencia2(CentroTrabajo centro) throws ABMCentroDeTrabajoException {
        if (centro.getId() == null) {
            return false;
        }
        Criteria criterio = Fachada.getInstancia().crearCriterio(CentroTrabajo.class);
        criterio.add(Restrictions.eq("id", centro.getId()));

        if (Fachada.getInstancia().buscar(CentroTrabajo.class, criterio).isEmpty()) {
            return false;
        } else {
            return true;
        }
    }
}
